import logging
from typing import Any, List

from sqlalchemy.ext.asyncio import AsyncSession
from starlette.requests import Request
from starlette_admin import EnumField, HasOne, action
from starlette_admin.contrib.sqla import ModelView
from starlette_admin.exceptions import ActionFailed

from src.application.order.enums import ReloadType
from src.application.server.enums import ServerPrivacy, ServerStatus, ServerType
from src.infrastructure.db.models import Proxy
from src.infrastructure.ssh.async_ssh_connector import get_proxies_from_config

logger = logging.getLogger(__name__)


class ServerView(ModelView):
    fields = [
        "id",
        "name",
        EnumField("status", enum=ServerStatus, select2=False),
        "description",
        "categories",
        "proxies",
        "ip_address",
        "inner_ip_address",
        "apache_port",
        "config_path",
        "proxy_type",
        "proxy_privacy",
        HasOne("provider", identity="proxy-provider", required=True),
        "ssh_port",
        HasOne("country", identity="country", required=True),
        "login",
        "password",
        "was_added",
    ]

    @action(
        name="import_proxies",
        text="Import proxies",
    )
    async def import_proxies(self, request: Request, pks: List[Any]) -> Any:
        session: AsyncSession = request.state.session
        for server in await self.find_by_pks(request, pks):
            success = 0
            errors = 0
            print(server)

            try:
                proxy_list = await get_proxies_from_config(
                    ip_address=server.ip_address,
                    ssh_port=server.ssh_port,
                    login=server.login,
                    password=server.password,
                    config_path=server.config_path,
                )
            except Exception as e:
                logger.exception(e)
                raise ActionFailed("Can't get proxies from server") from e

            for proxy in proxy_list:
                try:
                    proxy = Proxy(
                        login=proxy.get("login"),
                        password=proxy.get("password"),
                        port_https=proxy.get("port"),
                        server=server,
                    )
                    if server.proxy_type == ServerType.mobile:
                        proxy.reload_type = ReloadType.by_time
                        proxy.reload_period = 5
                        if server.proxy_privacy == ServerPrivacy.private:
                            proxy.reload_link = proxy.port_https
                        else:
                            proxy.authorization_type = None
                    session.add(proxy)
                    await session.commit()
                    success += 1
                except Exception as e:
                    logger.exception(e)
                    errors += 1

            return f"Proxies created. Successfully: {success}. With error: {errors}"
